package com.javasoft.service.XGX.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.javasoft.dao.XGX.QuestionDao;
import com.javasoft.dao.XGX.WrongTableDao;
import com.javasoft.entity.XGX.KnowledgePoint;
import com.javasoft.entity.XGX.Practice;
import com.javasoft.entity.XGX.Question;
import com.javasoft.entity.XGX.WrongQuestion;
import com.javasoft.service.XGX._interface.WrongTableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.javasoft.dao.XGX.KnowledgePointDao;

import java.util.*;


@Service
public class WrongTableImpl extends ServiceImpl<WrongTableDao, WrongQuestion> implements WrongTableService
{

    @Autowired
    private PracticeImpl practice_impl;

    @Autowired
    private QuestionDao questionDao;

    @Autowired
    private KnowledgePointDao knowledgePointDao;

    /**
     * 查询错题表
     * @param questionId
     * @param subject
     * @param knoPoint
     * @param des
     * @param type
     * @param difRank
     * @param currentPage
     * @param pageSize
     * @return
     */

    @Override
    public Page<WrongQuestion> searchWrongTable(Long questionId,String subject, String knoPoint,String des, String type, Integer difRank, Integer currentPage, Integer pageSize) {

        LambdaQueryWrapper<WrongQuestion> wrapper = new LambdaQueryWrapper<>();

        // 根据id精确查询
        if (questionId!= null) {
            wrapper.eq(WrongQuestion::getQuestionId, questionId);
            return super.page(new Page<>(currentPage, pageSize), wrapper);
        }
        // 根据题目描述des模糊查询
        else if (!"".equals(des) && des!= null) {
            wrapper.like(WrongQuestion::getDes, des);
            return super.page(new Page<>(currentPage, pageSize), wrapper);
        }

        // 根据科目查询
        else if (!"".equals(subject) && subject!= null) {
            if (!"".equals(knoPoint) && knoPoint!= null) {
                if (difRank!= null && difRank!= -1) {
                    wrapper.and(w -> {
                        w.like(WrongQuestion::getSubject, subject);
                        w.eq(WrongQuestion::getDifrank, difRank);
                        w.like(WrongQuestion::getKnopoint, knoPoint);
//                        w.ge(WrongQuestion::getFrequency, 2);
                    });
                    return super.page(new Page<>(currentPage, pageSize), wrapper);
                }
                wrapper.and(w -> {
                    w.like(WrongQuestion::getSubject, subject);
                    w.like(WrongQuestion::getKnopoint, knoPoint);
//                    w.ge(WrongQuestion::getFrequency, 2);
                });
                return super.page(new Page<>(currentPage, pageSize), wrapper);
            }
            if (!"".equals(type) && type!= null) {
                if (difRank!= null && difRank!= -1) {
                    wrapper.and(w -> {
                        w.like(WrongQuestion::getSubject, subject);
                        w.eq(WrongQuestion::getDifrank, difRank);
                        w.like(WrongQuestion::getType, type);
//                        w.ge(WrongQuestion::getFrequency, 2);
                    });
                    return super.page(new Page<>(currentPage, pageSize), wrapper);
                }
                wrapper.and(w -> {
                    w.like(WrongQuestion::getSubject, subject);
                    w.like(WrongQuestion::getType, type);
//                    w.ge(WrongQuestion::getFrequency, 2);
                });
                return super.page(new Page<>(currentPage, pageSize), wrapper);
            }
            if (difRank!= null && difRank!= -1) {
                wrapper.and(w -> {
                    w.like(WrongQuestion::getSubject, subject);
                    w.eq(WrongQuestion::getDifrank, difRank);
//                    w.ge(WrongQuestion::getFrequency, 2);
                });
                return super.page(new Page<>(currentPage, pageSize), wrapper);
            }
            wrapper.and(w -> {
                w.like(WrongQuestion::getSubject, subject);
//                w.ge(WrongQuestion::getFrequency, 2);
            });
            return super.page(new Page<>(currentPage, pageSize), wrapper);

        }
        else if (!"".equals(type) && type!= null) {
            wrapper.like(WrongQuestion::getType, type);
            return super.page(new Page<>(currentPage, pageSize), wrapper);
        }


        // 什么都没有就返回一个空页
        else {
            return new Page<>(currentPage, pageSize);
        }
    }

    /**
     * 错题库生成题目,
     * 输入科目,错题库根据错题的频率排序,选出出错频率较高的知识点用这些信息从题库筛选相应的题目生成训练题
     * @param subject
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public Page<Practice> getPracticeByWrongTable(String subject, Integer currentPage, Integer pageSize) {
        LambdaQueryWrapper<WrongQuestion> queryWrapper = new LambdaQueryWrapper<>();
        List<WrongQuestion> allWrongQuestion = baseMapper.selectList(null);


        LambdaQueryWrapper<KnowledgePoint> frequencyQueryWrapper = new LambdaQueryWrapper<>();
        // 可以按照频率降序排序，以便获取频率高的知识点排在前面，例如取前5
        frequencyQueryWrapper.orderByDesc(KnowledgePoint::getFrequency).last("LIMIT 5");
        List<KnowledgePoint> highFrequencyKnowledgePoints = knowledgePointDao.selectList(frequencyQueryWrapper);

        List<String> difficultKnoPointList = new ArrayList<>();
        for (KnowledgePoint knowledgePoint : highFrequencyKnowledgePoints) {
            difficultKnoPointList.add(knowledgePoint.getKnowledgePoint());
        }

        //根据这些知识点从题库中寻找题目生成训练题
        // 根据这些知识点从题库中寻找题目生成训练题，每个知识点最多选3道题
        List<Practice> practiceListByKnoPoint = new ArrayList<>();
        for (String knoPoint : difficultKnoPointList) {
            List<Practice> tmp = practice_impl.getPracticeList(subject, knoPoint, null, null, null);
            int count = 0;
            for (Practice practice : tmp) {
                if (count < 3) {
                    practiceListByKnoPoint.add(practice);
                    count++;
                } else {
                    break;
                }
            }
        }


        Page<Practice> showPage = new Page<>(currentPage, pageSize);
        int startIndex = (currentPage - 1) * pageSize;
        int endIndex = startIndex + pageSize;
        if (practiceListByKnoPoint.size() < endIndex) {
            // 如果实际列表长度小于要截取的结束索引，就把结束索引设置为列表实际长度
            endIndex = practiceListByKnoPoint.size();
        }
        List<Practice> subList = practiceListByKnoPoint.subList(startIndex, endIndex);

// 设置当前页记录
        showPage.setRecords(subList);

// 设置总记录数为practiceListByKnoPoint的实际长度
        showPage.setTotal(practiceListByKnoPoint.size());

// 计算总页数，总记录数除以每页大小，整除则为商，有余数则商加1
        int totalPages = practiceListByKnoPoint.size() % pageSize == 0?
                practiceListByKnoPoint.size() / pageSize :
                practiceListByKnoPoint.size() / pageSize + 1;
        showPage.setPages(totalPages);

        return showPage;



    }

    @Override
    public Page<WrongQuestion> getAllData(Integer currentPage, Integer pageSize) {
        // 创建Page对象，传入当前页码和每页显示数量
        Page<WrongQuestion> page = new Page<>(currentPage, pageSize);
        // 调用MyBatis-Plus的selectPage方法进行分页查询，第二个参数为查询条件，这里查询全部数据，传入null
        baseMapper.selectPage(page, null);
        return page;
    }

    @Override
    public String saveOrUpdateById(Long id) {
        WrongQuestion wrongQuestion = new WrongQuestion();
        Question tmp = questionDao.selectById(id);
        wrongQuestion.setQuestionId(id);
        wrongQuestion.setOpta(tmp.getOpta());
        wrongQuestion.setOptb(tmp.getOptb());
        wrongQuestion.setOptc(tmp.getOptc());
        wrongQuestion.setOptd(tmp.getOptd());
        wrongQuestion.setDes(tmp.getDes());
        wrongQuestion.setDifrank(tmp.getDifrank());
        wrongQuestion.setType(tmp.getType());
        wrongQuestion.setSubject(tmp.getSubject());
        wrongQuestion.setKnopoint(tmp.getKnopoint());

        if (wrongQuestion.getQuestionId() == null) {
            return "题目id为空,请完善";
        } else {
            LambdaQueryWrapper<WrongQuestion> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(WrongQuestion::getQuestionId, wrongQuestion.getQuestionId());

            // 根据questionId查询是否已存在记录
            WrongQuestion existingQuestion = baseMapper.selectOne(queryWrapper);

            if (existingQuestion == null) {
                // 如果不存在，执行保存操作
                save(wrongQuestion);
                // 获取错题的知识点
                String knowledgePoint = wrongQuestion.getKnopoint();
                // 更新知识点频率表中对应知识点的频率
                updateKnowledgePointFrequency(knowledgePoint, 1);
                String id_string = wrongQuestion.getQuestionId().toString();
                return "题目id:" + id_string + "保存成功";
            } else {

                // 使用update方法，传入更新的对象以及更新条件（依然以questionId为条件）
                baseMapper.update(wrongQuestion, queryWrapper);
                // 获取错题的知识点
                String knowledgePoint = wrongQuestion.getKnopoint();
                // 更新知识点频率表中对应知识点的频率（增加1，因为错题再次出现了）
                updateKnowledgePointFrequency(knowledgePoint, 1);
                String id_string = wrongQuestion.getQuestionId().toString();
                return "题目id:" + id_string + "更新成功";
            }
        }
    }

    @Override
    public String saveOrUpdateByBody(WrongQuestion wrongQuestion) {
        if (wrongQuestion.getQuestionId() == null) {
            return "题目id为空,请完善";
        } else {
            LambdaQueryWrapper<WrongQuestion> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(WrongQuestion::getQuestionId, wrongQuestion.getQuestionId());

            // 根据questionId查询是否已存在记录
            WrongQuestion existingQuestion = baseMapper.selectOne(queryWrapper);

            if (existingQuestion == null) {
                // 如果不存在，执行保存操作
                save(wrongQuestion);
                // 获取错题的知识点
                String knowledgePoint = wrongQuestion.getKnopoint();
                // 更新知识点频率表中对应知识点的频率
                updateKnowledgePointFrequency(knowledgePoint, 1);
                String id_string = wrongQuestion.getQuestionId().toString();
                return "题目id:" + id_string + "保存成功";
            } else {
                // 如果存在，更新相关属性
//                wrongQuestion.setFrequency(existingQuestion.getFrequency() + 1);
                // 使用update方法，传入更新的对象以及更新条件（依然以questionId为条件）
                baseMapper.update(wrongQuestion, queryWrapper);
                // 获取错题的知识点
                String knowledgePoint = wrongQuestion.getKnopoint();
                // 更新知识点频率表中对应知识点的频率（增加1，因为错题再次出现了）
                updateKnowledgePointFrequency(knowledgePoint, 1);
                String id_string = wrongQuestion.getQuestionId().toString();
                return "题目id:" + id_string + "更新成功";
            }
        }
    }
    /**
     * 更新知识点频率表中指定知识点的频率
     *
     * @param knowledgePoint 要更新频率的知识点
     * @param increment      频率的增量（通常保存错题时为1，表示出现次数增加1次）
     */
    private void updateKnowledgePointFrequency(String knowledgePoint, int increment) {
        LambdaQueryWrapper<KnowledgePoint> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(KnowledgePoint::getKnowledgePoint, knowledgePoint);
        KnowledgePoint existingFrequency = knowledgePointDao.selectOne(queryWrapper);
        if (existingFrequency == null) {
            // 如果知识点不存在频率表中，插入新记录
            KnowledgePoint newEntity = new KnowledgePoint();
            newEntity.setKnowledgePoint(knowledgePoint);
            newEntity.setFrequency(increment);
            knowledgePointDao.insert(newEntity);
        } else {
            // 如果存在，更新频率值
            existingFrequency.setFrequency(existingFrequency.getFrequency() + increment);
            knowledgePointDao.updateById(existingFrequency);
        }
    }

    @Override
    public String deleteBatchIds(List<Integer> ids) {
        boolean flag = removeByIds(ids);
        if (flag) {
            return "delete success";
        }
        else {
            return "delete fail";
        }
    }


}







